import { login, logout, getInfo } from '@/api/acl/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter, constantRoutes, allAsyncRoutes, randomRoute } from '@/router'
import router from '@/router'
import cloneDeep from 'lodash/cloneDeep'

// const getDefaultState = () => {
//   return {
//     token: getToken(),
//     name: '',
//     avatar: ''
//   }
// }


//  通过返回来的name名称数组，从所有的异步路由当中过滤出，需要动态注册的异步路由
function filterAsyncRoutes (allAsyncRoutes, routeNames) {
  const result = allAsyncRoutes.filter(item => {
    // 判断拿到的一级路由，名称是不是在返回的名称里面，如果是我们就要，不是就不要了
    if (routeNames.indexOf(item.name) !== -1) {
      // 判断一级路由是不是有子路由，如果有，那么也得把子路由过滤出来
      if (item.children && item.children.length) {
        item.children = filterAsyncRoutes(item.children, routeNames)
      }
      return true
    }
  })
  return result
}




// const state = getDefaultState()
const state = {
  token: getToken(),
  name: '',
  avatar: '',

  //下面是和权限数据信息相关的
  buttons: [], //和按钮信息相关的
  roles: [], //和用户角色相关的
  routes: [], // 到时候存储的是这个用户对应的所有的路由组成的数组（包含常量、异步、任意路由），不是路由的name值
  asyncRoutes: [] //到时候存储的是这个用户对应的所有需要动态注册的异步路由，也不是路由的name值
}

const mutations = {
  // RESET_STATE: (state) => {
  //   Object.assign(state, getDefaultState())
  // },
  RESET_STATE (state) {
    state.token = ''
    state.name = ''
    state.avatar = ''
    state.buttons = []
    state.routes = []
    state.asyncRoutes = []
    state.roles = []
  },

  SET_TOKEN: (state, token) => {
    state.token = token
  },
  // SET_NAME: (state, name) => {
  //   state.name = name
  // },
  // SET_AVATAR: (state, avatar) => {
  //   state.avatar = avatar
  // }

  SET_USERINFO (state, userInfo) {
    state.name = userInfo.name
    state.avatar = userInfo.avatar
    // state.buttons = userInfo.buttons
    state.roles = userInfo.roles
  },


  SET_ROUTES (state, asyncRoutes) {
    state.asyncRoutes = asyncRoutes
    state.routes = constantRoutes.concat(asyncRoutes, randomRoute)  //获取到当前这个用户所有的路由
    //动态注册路由，让用户对应的路由注册到路由器
    router.addRoutes([...asyncRoutes, randomRoute])  //动态的给注册路由的数组，添加需要动态注册的路由
  }

}

const actions = {
  // user login
  // login({ commit }, userInfo) {
  //   const { username, password } = userInfo
  //   return new Promise((resolve, reject) => {
  //     login({ username: username.trim(), password: password }).then(response => {
  //       const { data } = response
  //       commit('SET_TOKEN', data.token)
  //       setToken(data.token)
  //       resolve()
  //     }).catch(error => {
  //       reject(error)
  //     })
  //   })
  // },

  async login ({ commit }, userInfo) {
    const { username, password } = userInfo
    const result = await login({ username: username.trim(), password: password })
    if (result.code === 20000 || result.code === 200) {
      const { data } = result
      localStorage.setItem('TOKEN', data.token)
      commit('SET_TOKEN', data.token)
      setToken(data.token)
      return 'ok'
    } else {
      return Promise.reject('failed')
    }
  },


  // get user info
  getInfo ({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        const { data } = response
        if (!data) {
          return reject('Verification failed, please Login again.')
        }
        commit('SET_USERINFO', data)
        localStorage.setItem('BUTTONS', data.buttons)
        commit('SET_ROUTES', filterAsyncRoutes(cloneDeep(allAsyncRoutes), data.routes))
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // user logout
  logout ({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        localStorage.removeItem('TOKEN')
        resetRouter() //重置路由
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken ({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true, // 命名空间开启  
  // 每个模块无论是state还是其余的核心概念  都可以定义重复的名字
  // 如果加上它，那么在去dispatch的时候  users/xxxx   app/xxxx    
  state,
  mutations,
  actions
}

